package per.chenxin.util.tcp.http;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.codec.binary.Base64;

public class ProxyEntity implements Serializable {

	private static final long serialVersionUID = 2457692570968745939L;

	static ProxyEntity proxyEntity;

	public List<Entity> listEntity;

	int localPort = 0;

	String proxyHost = null;

	int proxyPort = 0;

	String username = null;

	String password = null;

	String authorization = null;

	String checkMethod = null;

	String checkUrl = null;

	String checkResult = null;

	public int getLocalPort() {
		return localPort;
	}

	public void setLocalPort(int localPort) {
		this.localPort = localPort;
	}

	public String getProxyHost() {
		return proxyHost;
	}

	public void setProxyHost(String proxyHost) {
		this.proxyHost = proxyHost;
	}

	public int getProxyPort() {
		return proxyPort;
	}

	public void setProxyPort(int proxyPort) {
		this.proxyPort = proxyPort;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getAuthorization() {
		if (authorization != null)
			return authorization;

		if (username == null || password == null)
			return null;

		return new String(Base64.encodeBase64((username + ":" + password)
				.getBytes()));
	}

	public void setAuthorization(String authorization) {
		this.authorization = authorization;
	}

	public String getCheckMethod() {
		return checkMethod;
	}

	public void setCheckMethod(String checkMethod) {
		this.checkMethod = checkMethod;
	}

	public String getCheckUrl() {
		return checkUrl;
	}

	public void setCheckUrl(String checkUrl) {
		this.checkUrl = checkUrl;
	}

	public String getCheckResult() {
		return checkResult;
	}

	public void setCheckResult(String checkResult) {
		this.checkResult = checkResult;
	}

	public static ProxyEntity getProxyEntity() {

		return proxyEntity;
	}

	public static ProxyEntity getNewProxyEntity() {

		ProxyEntity proxyEntity = new ProxyEntity();
		return proxyEntity;
	}

	private ProxyEntity() {
		listEntity = new LinkedList<Entity>();
	}

	public void addEntity(Entity entity) {
		listEntity.add(entity);
	}

	static public ProxyEntity readFromIni(String strIniFile)
			throws FileNotFoundException, IOException {
		Properties properties;
		properties = new Properties();
		properties.load(new FileInputStream(strIniFile));

		int localPort = Integer.parseInt((String) properties.get("LocalPort"));

		String socketProxy = (String) properties.get("socket");
		int socketProxyPort = 0;
		String socketProxyHost = null;
		String[] strsTemp;
		if (socketProxy != null) {
			strsTemp = socketProxy.split(":");
			try {
				socketProxyPort = Integer.parseInt(strsTemp[1]);
			} catch (NumberFormatException nfe) {
				System.exit(-1);
			}
			socketProxyHost = strsTemp[0];
		}

		String socketName = null;
		String socketPassword = null;
		String socketAuth = (String) properties.get("socket_auth");
		if (socketAuth == null || socketAuth.trim().length() == 0) {
			socketName = (String) properties.get("socket_name");
			socketPassword = (String) properties.get("socket_password");
			if (socketPassword == null)
				socketPassword = "";
			if (socketName != null && socketName.trim().length() > 0) {
				socketAuth = new String(
						Base64.encodeBase64((socketName + ":" + socketPassword)
								.getBytes()));
			}
		}

		ProxyEntity proxyEntity = ProxyEntity.getNewProxyEntity();
		proxyEntity.setLocalPort(localPort);
		proxyEntity.setProxyHost(socketProxyHost);
		proxyEntity.setProxyPort(socketProxyPort);
		proxyEntity.setUsername(socketName);
		proxyEntity.setAuthorization(socketAuth);

		int proxyCount = Integer
				.parseInt((String) properties.get("ProxyCount"));

		for (int i = 1; i <= proxyCount; i++) {
			String step = (String) properties.get("step_" + i);
			if (step == null)
				System.exit(-1);
			strsTemp = step.split(":");
			if (strsTemp.length != 2)
				System.exit(-1);

			int proxyPort = 0;
			try {
				proxyPort = Integer.parseInt(strsTemp[1]);
			} catch (NumberFormatException nfe) {
				System.exit(-1);
			}
			String proxyHost = strsTemp[0];
			String name = null;
			String password = null;
			String auth = (String) properties.get("step_" + i + "_auth");
			if (auth == null || auth.trim().length() == 0) {
				name = (String) properties.get("step_" + i + "_name");
				password = (String) properties.get("step_" + i + "_password");
				if (password == null)
					password = "";
				if (name != null && name.trim().length() > 0) {
					auth = new String(
							Base64.encodeBase64((name + ":" + password)
									.getBytes()));
				}
			}

			Entity entity = new Entity(proxyHost, proxyPort, name, password,
					auth);
			proxyEntity.addEntity(entity);
		}

		proxyEntity.setCheckMethod((String) properties.get("check_method"));
		proxyEntity.setCheckUrl((String) properties.get("check_url"));
		proxyEntity.setCheckResult((String) properties.get("check_result"));

		return proxyEntity;

	}

	static public ProxyEntity inport() throws FileNotFoundException,
			IOException, ClassNotFoundException {

		return inport(ProxyEntity.class.getSimpleName());

	}

	static public ProxyEntity inport(String strFilename)
			throws FileNotFoundException, IOException, ClassNotFoundException {

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				strFilename));
		try {
			return (ProxyEntity) ois.readObject();
		} finally {
			ois.close();
		}

	}

	static public void export(ProxyEntity proxyEntity, String strFilename)
			throws FileNotFoundException, IOException {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(
				strFilename));
		try {
			oos.writeObject(proxyEntity);
			oos.flush();
		} finally {
			oos.close();
		}
	}

	static public void export(ProxyEntity proxyEntity)
			throws FileNotFoundException, IOException {
		export(proxyEntity, ProxyEntity.class.getSimpleName());
	}

	static public void export(String strFilename) throws FileNotFoundException,
			IOException {
		export(proxyEntity, ProxyEntity.class.getSimpleName());
	}

	static public void export() throws FileNotFoundException, IOException {
		export(proxyEntity);
	}

	static {
		proxyEntity = new ProxyEntity();
		try {
			proxyEntity = inport();
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		} catch (ClassNotFoundException e) {
		}
	}

}
